Lab8 - Codificação de Áudio com ffmpeg
Profs. Celso S. Kurashima e Mário Minami
Alunos:
Neste laboratório, foram utilizadas as bibliotecas Scipy, Librosa e codec ffmpeg, dentro do ambiente de desenvolvimento do Google Colab, para estudar técnicas de codificações e manipulações de áudio, utilizando a linguagem Python.
Dentre as atividades de processamento desenvolvidas, foi possível atingir os seguintes objetivos:
Objetivos:
Link para o ambiente Colab utilizado no desenvolvimento desta prática:
Importando todas as Bibliotecas utilzadas durante esta prática de laboratório:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
import librosa
import librosa.display
import IPython.display
import math
import pandas as pd
import os
Adquirindo os Arquivos de áudio do repositório do GitHub:
%%bash
wget -q https://github.com/JohnGarrido/ESTI019/blob/main/lab_8/abba0__320k.wav?raw=true
mv abba0__320k.wav?raw=true abba0__320k.wav
Abaixo, temos a função display_audio(file_path: str,plot=False), utilzada para ler o arquivo de áudio com a biblioteca Librosa e visualizá-lo dentro do ambiente do Google Colab.
Adicionalmente, a função recebe um parâmetro opcional, para plotar a waveform do aúdio anteriormente lido.
def display_audio(file_path: str,plot=False) -> None:
fer , sr = librosa.load(file_path)
print(type(fer), type(sr))
print(fer.shape, sr)
# Player será aberto! AGUARDE até abrir!
display(IPython.display.Audio(data=fer, rate=sr))
if plot:
plt.figure()
fig, ax = plt.subplots(figsize=(15, 5))
librosa.display.waveplot(fer, sr)
plt.title("Plot Waveform "+file_path)
Arquivo .wav full
abba320k = 'abba0__320k.wav'
display_audio(abba320k)
<class 'numpy.ndarray'> <class 'int'> (3041592,) 22050
Espectrograma Original
def render_espectogram(file_path: str) -> None:
fer , sr = librosa.load(file_path)
plt.figure(figsize=(20, 5))
D = librosa.amplitude_to_db(np.abs(librosa.stft(fer)), ref=np.max)
librosa.display.specshow(D, x_axis='time',y_axis='linear')
plt.colorbar(format='%+2.0f dB')
plt.title('Linear-frequency power spectrogram '+ file_path)
render_espectogram(abba320k)
Conversão wav em mp3, 128kbps
!ffmpeg -i abba0__320k.wav -codec:a libmp3lame -b:a 128k abba128k.mp3 -loglevel error
Áudio e Espectrograma do arquivo codificado
abba128k = './abba128k.mp3'
display_audio(abba128k)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
<class 'numpy.ndarray'> <class 'int'> (3041592,) 22050
Espectrograma do Arquivo codificado a 128kbps
render_espectogram(abba128k)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
Codificando a 64kbps
# Codifcando a 64kbps com logs em nível apenas de erro para diminuir o verbose
!ffmpeg -i abba0__320k.wav -codec:a libmp3lame -b:a 64k abba64k.mp3 -loglevel error
Espectrograma do arquivo a 64kbps
abba64k = './abba64k.mp3'
render_espectogram(abba64k)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
Audio do arquivo
abba64k = 'abba64k.mp3'
display_audio(abba64k)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
<class 'numpy.ndarray'> <class 'int'> (3041592,) 22050
Conversão de Codecs
# Conversão de codecs a 128kbps com logs em nível apenas de erro para diminuir o verbose
!ffmpeg -i abba128k.mp3 -c:a libvorbis abba128k.ogg -loglevel error
!ls -l
total 28884 -rw-r--r-- 1 root root 24333050 Nov 25 14:22 abba0__320k.wav -rw-r--r-- 1 root root 2208420 Nov 25 14:22 abba128k.mp3 -rw-r--r-- 1 root root 1916940 Nov 25 14:23 abba128k.ogg -rw-r--r-- 1 root root 1104381 Nov 25 14:23 abba64k.mp3 drwxr-xr-x 1 root root 4096 Nov 18 14:36 sample_data
Faça o procedimento para mais três taxas, 32k, 16k e 8kbps.
# Codifcando a 32k, 16k e 8kbps com logs em nível apenas de erro para diminuir o verbose
!ffmpeg -i abba0__320k.wav -codec:a libmp3lame -b:a 32k abba32k.mp3 -loglevel error
!ffmpeg -i abba0__320k.wav -codec:a libmp3lame -b:a 16k abba16k.mp3 -loglevel error
!ffmpeg -i abba0__320k.wav -codec:a libmp3lame -b:a 8k abba8k.mp3 -loglevel error
Alterando a velocidade
!ffmpeg -i abba128k.mp3 -filter:a "atempo=2.0" -vn abba128k_v2.mp3 -loglevel error
Audio v2 - Duas vezes a velocidade do áudio Original
abba128k_2 = './abba128k_v2.mp3'
display_audio(abba128k_2,plot=True)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
<class 'numpy.ndarray'> <class 'int'> (1520881,) 22050
<Figure size 432x288 with 0 Axes>
Mude para um tempo mais lento - 25% mais lento que o áudio original
!ffmpeg -i abba128k.mp3 -filter:a "atempo=0.75" -vn abba128k_v075.mp3 -loglevel error
abba128k_075 = './abba128k_v075.mp3'
display_audio(abba128k_075,plot=True)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
<class 'numpy.ndarray'> <class 'int'> (4055240,) 22050
<Figure size 432x288 with 0 Axes>
Repita todos os passos para um arquivo de áudio original de preferência de um CD, mas ao invés da opção codificação com taxa fixa (-b:a), use -q:a N (com N um número de 0 a 9), de 320 a 65kbps.
Carregando o Arquivo de Áudio
%%bash
wget -q https://github.com/JohnGarrido/ESTI019/blob/main/lab_8/kisskiss.mp3?raw=true
mv kisskiss.mp3?raw=true kisskiss.mp3
Display do Arquivo Original
kisskiss = 'kisskiss.mp3'
display_audio(kisskiss)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
<class 'numpy.ndarray'> <class 'int'> (5649144,) 22050
Espectograma do Áudio Original
render_espectogram(kisskiss)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
Codificando o arquivo (-q:a N)
!ffmpeg -i kisskiss.mp3 -codec:a libmp3lame -q:a 9 kisskiss_q9.mp3 -loglevel error
Display do Arquivo Codificado (-q:a N=9)
kisskiss_q9 = 'kisskiss_q9.mp3'
display_audio(kisskiss_q9)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
<class 'numpy.ndarray'> <class 'int'> (5649144,) 22050
Espectograma do Áudio Codificado
render_espectogram(kisskiss_q9)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
Reduzindo a Velocidade do Áudio Original
!ffmpeg -i kisskiss.mp3 -filter:a "atempo=0.75" -vn kisskiss_v075.mp3 -loglevel error
kisskiss_v075 = "kisskiss_v075.mp3"
display_audio(kisskiss_v075,plot=True)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
<class 'numpy.ndarray'> <class 'int'> (7531384,) 22050
<Figure size 432x288 with 0 Axes>
Aumentando a Velocidade do Áudio Original
!ffmpeg -i kisskiss.mp3 -filter:a "atempo=2" -vn kisskiss_v2.mp3 -loglevel error
kisskiss_v2 = "kisskiss_v2.mp3"
display_audio(kisskiss_v2,plot=True)
/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.
warnings.warn("PySoundFile failed. Trying audioread instead.")
<class 'numpy.ndarray'> <class 'int'> (2824440,) 22050
<Figure size 432x288 with 0 Axes>

Através do Espectrograma, podemos ver que para o áudio codificados com o parâmetro -q:a 9, todas as frequëncias superiores à 8kHz foram perdidas.
Sendo assim, houve uma forte perda de informação nas frequências mais elevadas, relativamente ao áudio original.
#Obtem o Tamanho dos arquivos de audio Comprimidos e Originais
original = os.path.getsize("/content/kisskiss.mp3")
codificado = os.path.getsize("/content/kisskiss_q9.mp3")
#Monta Tabela com os dados de interesse
df = pd.DataFrame(data=[original,codificado]).T
df.columns=["Original(Bytes)","Codificado(Bytes)"]
df["Space Saving(%)"] = ((df["Codificado(Bytes)"]/df["Original(Bytes)"])-1)*100
df["Compression Ratio(%)"] = (df["Original(Bytes)"]/df["Codificado(Bytes)"])*100
df["Audio"] = "kisskiss_q9.mp3"
df
| Original(Bytes) | Codificado(Bytes) | Space Saving(%) | Compression Ratio(%) | Audio | |
|---|---|---|---|---|---|
| 0 | 4600161 | 3436387 | -25.298549 | 133.866209 | kisskiss_q9.mp3 |
#Obtem o Tamanho dos arquivos de audio Comprimidos e Originais
size = os.path.getsize("/content/abba128k.mp3"),os.path.getsize("/content/abba64k.mp3"),os.path.getsize("/content/abba32k.mp3"),os.path.getsize("/content/abba16k.mp3"),os.path.getsize("/content/abba8k.mp3")
original = os.path.getsize("/content/abba0__320k.wav")
#Monta Tabela com os dados de interesse
df = pd.DataFrame(data=[size]).T
df.columns=["Size(Bytes)"]
df["Space Saving(%)"] = ((df["Size(Bytes)"]/original)-1)*100
df["Compression Ratio(%)"] = (original/df["Size(Bytes)"])*100
df["Audio"] = ["abba128k.mp3","abba64k.mp3","abba32k.mp3","abba16k.mp3","abba8k.mp3"]
df
| Size(Bytes) | Space Saving(%) | Compression Ratio(%) | Audio | |
|---|---|---|---|---|
| 0 | 2208420 | -90.924196 | 1101.830721 | abba128k.mp3 |
| 1 | 1104381 | -95.461395 | 2203.320231 | abba64k.mp3 |
| 2 | 552466 | -97.729565 | 4404.442988 | abba32k.mp3 |
| 3 | 552466 | -97.729565 | 4404.442988 | abba16k.mp3 |
| 4 | 552466 | -97.729565 | 4404.442988 | abba8k.mp3 |
Neste laboratório, através da manipulação de dados de áudio, foi possível aplicar técnicas de codificação de sinais, em arquivos de áudio/voz musicais.
Através das bibliotecas scipy e librosa e codec ffmpeg, foi possível realizar processos de codficação para compressão e manipulação de arquivos de áudio, alterando sua qualidade, quantidade de informação armazenada e velocidade de reprodução.
A partir dos sinais analisados, foram extraídas componentes como:
Leitura do áudio, extração de trechos, análise de waveform
Codificação com diferentes taxas de bit rate, alterando a fidelidade da informação armazenada nos áudios e verificando sua eficiência de compressão